package com.ocom.mqsubsidy.business.zkzl;

import com.alibaba.fastjson.JSON;
import com.ocom.common.dto.DockKeyDto;
import com.ocom.common.dto.MqPaymentCallBackDto;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.entity.company.EntityDockKey;
import com.ocom.common.entity.pay.EntityAbnormal;
import com.ocom.common.mq.ZkzlConfig;
import com.ocom.common.request.company.GetDockApiUrlRequest;
import com.ocom.common.request.payhandle.GetRecordByOrderNoRequest;
import com.ocom.common.request.payhandle.MqPaymentCallBackRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.zkzl.SecretRule;
import com.ocom.common.utils.zkzl.SecretUtil;
import com.ocom.common.utils.zkzl.dto.ZKZLReturnDto;
import com.ocom.common.vo.company.DockApiUrlVo;

import com.ocom.mqsubsidy.feign.CompanyClientService;
import com.ocom.mqsubsidy.feign.PayHandleClientService;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Component
public class ZkzlMqListener {

    private Logger logger = LoggerFactory.getLogger(ZkzlMqListener.class);

    @Autowired
    private PayHandleClientService payHandleClientService;

    @Autowired
    private CompanyClientService companyClientService;

    static final String DOCK_API_CODE = "zkzl#paymentCallBack";
    static final String DOCK_CODE = "zkzl";
    static final String SID = "170000000000051001";//dockServer中获取？

    @RabbitListener(queues = ZkzlConfig.QUEUE)
    public void process(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
        try {

            logger.info("message【{}】", message);
            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
            MqPaymentCallBackDto callBackVo = JSON.parseObject(msg, MqPaymentCallBackDto.class);
            logger.info("消费数据【{}】", callBackVo);

            GetRecordByOrderNoRequest getRecordByOrderNoRequest = new GetRecordByOrderNoRequest();
            getRecordByOrderNoRequest.setCompanyId(callBackVo.getComId());
            getRecordByOrderNoRequest.setPId(callBackVo.getPId());
            getRecordByOrderNoRequest.setOrderNo(callBackVo.getTradeNo());
            Result getRecordByOrdernoResult = payHandleClientService.getRecordByOrderno(getRecordByOrderNoRequest);
            if (200 == getRecordByOrdernoResult.getCode() && null != getRecordByOrdernoResult.getData()) {
                EntityXfRecordProcess xfRecordProcesses = JSON.parseObject(JSON.toJSONString(getRecordByOrdernoResult.getData()), EntityXfRecordProcess.class);

                if (null != xfRecordProcesses && -1 != xfRecordProcesses.getPayState()) {

                    ZKZLReturnDto returnDto = new ZKZLReturnDto();
                    EntityDockKey entityDockKey = getDockKey(DOCK_CODE, returnDto);

                    GetDockApiUrlRequest getDockApiUrlRequest = new GetDockApiUrlRequest();
                    getDockApiUrlRequest.setComId(entityDockKey.getComId());
                    getDockApiUrlRequest.setDockCode(DOCK_CODE);
                    getDockApiUrlRequest.setGrade(0);
                    Result getDockApiUrlResult = companyClientService.getDockApiUrl(getDockApiUrlRequest);

                    if (null == getDockApiUrlResult || null == getDockApiUrlResult.getData()) {
                        throw new Exception("读取通讯接口URL失败");
                    }
                    List<DockApiUrlVo> getDockApiUrlList = JSON.parseArray(JSON.toJSONString(getDockApiUrlResult.getData()), DockApiUrlVo.class);
                    Optional<DockApiUrlVo> dockApiUrl = getDockApiUrlList.stream().filter(o -> o.getDockApiCode().equals(DOCK_API_CODE)).findFirst();
                    if (dockApiUrl.isPresent()) {
                        String reqUrl = dockApiUrl.get().getRequestUrl();

                        MqPaymentCallBackRequest mqPaymentCallBackRequest = new MqPaymentCallBackRequest();
                        mqPaymentCallBackRequest.setOrderNumber(callBackVo.getTradeNo().replace("ZK", "").trim());
                        mqPaymentCallBackRequest.setPaymentNumber(callBackVo.getTradeNo());
                        mqPaymentCallBackRequest.setPaymentStatus(xfRecordProcesses.getPayState());
                        String requestParam = JSON.toJSONString(mqPaymentCallBackRequest);

                        SecretRule secretRule = new SecretRule().setSid(SID).setAes(entityDockKey.getAesKey()).setMd5(entityDockKey.getMd5Key());
                        String aesData = SecretUtil.encryptByAES(secretRule, requestParam);
                        String md5Data = SecretUtil.encryptByMD5(secretRule, aesData);
                        logger.info("加密前参数data:" + requestParam);
                        logger.info("X-Sign:" + md5Data + ",参数data:" + aesData);

                        //发送签名信息获取返回签名信息
                        reqUrl += "?data=" + aesData;
                        Map responseMap = SecretUtil.doGet(reqUrl, SID, md5Data);
                        logger.info("接收到的报文：" + responseMap);

//			如果返回Code==200，调用消费操作微服务2.3.8中卡水控支付sendByOrderno
                        if (200 == Double.valueOf(responseMap.get("Code").toString()).intValue()) {
                            xfRecordProcesses.setSendState(1);
                            payHandleClientService.sendByOrderno(xfRecordProcesses);
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @RabbitListener(queues = ZkzlConfig.DIE_QUEUE)
    public void processForDie(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {

        try {
            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
            MqPaymentCallBackDto vo = JSON.parseObject(msg, MqPaymentCallBackDto.class);
            EntityAbnormal entityAbnormal = new EntityAbnormal();
            entityAbnormal.setComId(vo.getComId());
            entityAbnormal.setPlatOrderNo(vo.getTradeNo().toString());
            entityAbnormal.setType(2);
            entityAbnormal.setRemark("mq迁移失败");
            payHandleClientService.addAbnormal(entityAbnormal);
        } catch (Exception e) {
            logger.error("异步迁移成功订单失败  死信队列记录  - 异常, 【{】】", e);
        }

        //死信队列放弃
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        //插入异常  TODO
        logger.info("异步迁移成功订单失败  死信队列记录 , 【{】】", message);
    }

    private EntityDockKey getDockKey(String dockCode, ZKZLReturnDto returnDto) throws Exception {
        DockKeyDto dockKeyDto = new DockKeyDto();
        dockKeyDto.setDockCode(dockCode);
        dockKeyDto.setGrade(20);
        Result dockKeyResult = companyClientService.getDockKey(dockKeyDto);
        if (dockKeyResult == null || 200 != dockKeyResult.getCode()) {
            returnDto.setReturnCode(206);
            returnDto.setReturnMessage("密钥不存在");
            throw new Exception(returnDto.getReturnMessage());
        }
        EntityDockKey entityDockKey = JSON.parseObject(JSON.toJSONString(dockKeyResult.getData()), EntityDockKey.class);
        if (null == entityDockKey || StringUtils.isBlank(entityDockKey.getMd5Key()) || StringUtils.isBlank(entityDockKey.getAesKey())) {
            returnDto.setReturnCode(206);
            returnDto.setReturnMessage("密钥不存在");
            throw new Exception(returnDto.getReturnMessage());
        }
        return entityDockKey;
    }


}
